#include "wled.h"

#define WStyle_Customize 0
#define WStyle_Splash (0x0000000e | 0x00000001)

static QLabel* smallFontLabel(const char *str, int size=8)
{
	static QFont font;
	font.setPointSize(size);
	QLabel* l = new QLabel(str);
	l->setFont(font);
	return l;
}

WLed::WLed(QWidget *parent) 
	: QWidget(parent, (Qt::WindowFlags)(WStyle_Customize | WStyle_Splash) ) // no title bar
{
	resize(320, 240);
	
	/* setup colorful palette*/
	QLabel dummy;
	int j;
	for(j=0;j<3;j++)
		this->lights[j].palette = new QPalette(dummy.palette());
	this->lights[RED].palette->setColor(QPalette::Foreground, Qt::red);
	this->lights[GREEN].palette->setColor(QPalette::Foreground, Qt::green);
	this->lights[BLUE].palette->setColor(QPalette::Foreground, Qt::blue);

	QHBoxLayout *titleLayout = new QHBoxLayout;
	titleLayout->addWidget( smallFontLabel("Simulator for Delcom VSI", 9), 0, Qt::AlignLeft );
	titleLayout->addStretch();
	titleLayout->addWidget( smallFontLabel("homer.xing@gmail.com"), 0, Qt::AlignRight );
	
	QGridLayout *lightsLayout = new QGridLayout;
	/* add row title */
	lightsLayout->addWidget( new QLabel("red"), 0, 1, Qt::AlignCenter );
	lightsLayout->addWidget( new QLabel("green"), 0, 2, Qt::AlignCenter );
	lightsLayout->addWidget( new QLabel("blue"), 0, 3, Qt::AlignCenter );
	/* add column title */
	lightsLayout->addWidget( new QLabel("state"), 1, 0, Qt::AlignCenter );
	lightsLayout->addWidget( new QLabel("lightness"), 2, 0, Qt::AlignCenter ); // add '\n' to get multi-line label
	lightsLayout->addWidget( new QLabel("freq"), 3, 0, Qt::AlignCenter );
	lightsLayout->addWidget( new QLabel("on/off time"), 4, 0, Qt::AlignCenter );
	/* add labels */
	int i;
	for(i=0;i<3;i++)
	{
		/* default label text */
		this->lights[i].state = new QLabel("OFF");
		this->lights[i].lightness = new QLabel("255");
		this->lights[i].freq = new QLabel("100");
		this->lights[i].onofftime = new QLabel("255/255");
		this->lights[i].ontime = 255;
		this->lights[i].offtime = 255;
		/* change foreground color */
		this->lights[i].state->setPalette(*this->lights[i].palette);
		this->lights[i].lightness->setPalette(*this->lights[i].palette);
		this->lights[i].freq->setPalette(*this->lights[i].palette);
		this->lights[i].onofftime->setPalette(*this->lights[i].palette);
		/* align center */
		lightsLayout->addWidget( this->lights[i].state, 1, i+1, Qt::AlignCenter);
		lightsLayout->addWidget( this->lights[i].lightness, 2, i+1, Qt::AlignCenter);
		lightsLayout->addWidget( this->lights[i].freq, 3, i+1, Qt::AlignCenter);
		lightsLayout->addWidget( this->lights[i].onofftime, 4, i+1, Qt::AlignCenter);
	}
	
	QHBoxLayout *ldspkerLayout = new QHBoxLayout;
	ldspkerLayout->addWidget( new QLabel("loudspeaker: ") );
	ldspkerLayout->addWidget( this->lspker = smallFontLabel("quiet", 9) );
	ldspkerLayout->addStretch();
	
	/* alloc urbmsgs buffer and urb labels*/
	int k;
	for(k=0;k<4;k++)
	  {
		this->urbmsgs[k] = new char[100];
		strcpy(this->urbmsgs[k], "<none>");
		this->urb[k] = smallFontLabel(this->urbmsgs[k], 9);
	  }
	
	QGridLayout *urbLayout = new QGridLayout;
	urbLayout->addWidget( new QLabel("urb: "), 0, 0, Qt::AlignHCenter |  Qt::AlignTop );
	urbLayout->addWidget( this->urb[0], 0, 1, Qt::AlignLeft );
	urbLayout->addWidget( this->urb[1], 1, 1, Qt::AlignLeft );
	urbLayout->addWidget( this->urb[2], 2, 1, Qt::AlignLeft );
	urbLayout->addWidget( this->urb[3], 3, 1, Qt::AlignLeft );
	
	QHBoxLayout *dummy2 = new QHBoxLayout;
	dummy2->addLayout(urbLayout);
	dummy2->addStretch();
	
	QVBoxLayout *mainLayout = new QVBoxLayout;
	mainLayout->addLayout(titleLayout);
	mainLayout->addLayout(lightsLayout);
	mainLayout->addLayout(ldspkerLayout);
	mainLayout->addLayout(dummy2);
	mainLayout->addStretch();
	this->setLayout(mainLayout);
}

void WLed::setstate(int color, int state)
{
	static const char *label[]={"ON","FLASH","OFF"};
	
	printf("setstate color %d state %d\n", color, state);
	
	if(color>=0 && color<3 && state>=0 && state<3)
	{
		this->lights[color].state->setText( label[state] );
		if(state!=2)
		{
			/* not OFF, hence show labels. */
			this->lights[color].lightness->show();
			this->lights[color].freq->show();
			this->lights[color].onofftime->show();
		}
		else
		{
			/* is OFF, hide labels. */
			this->lights[color].lightness->hide();
			this->lights[color].freq->hide();
			this->lights[color].onofftime->hide();
		}
	}
}

void WLed::setlightness(int color, int lightness)
{
	printf("setlightness color %d lightness %d\n", color, lightness);
	
	if(color>=0 && color<3 && lightness>=0 && lightness<256)
		this->lights[color].lightness->setText( QString("%1").arg(lightness) );
}

void WLed::setfreq(int color, int freq)
{
	printf("setfreq color %d freq %d\n", color, freq);
	
	if(color>=0 && color<3 && freq>=0 && freq<256)
		this->lights[color].freq->setText( QString("%1").arg(freq) );
}

void WLed::setontime(int color, int ontime)
{
	printf("setontime color %d ontime %d\n", color, ontime);
	
	if(color>=0 && color<3 && ontime>=0 && ontime<256)
	{
		this->lights[color].ontime = ontime;
		this->lights[color].onofftime->setText( QString("%1/%2")
			.arg(this->lights[color].ontime)
			.arg(this->lights[color].offtime) );
	}
}

void WLed::setofftime(int color, int offtime)
{
	printf("setofftime color %d offtime %d\n", color, offtime);
	
	if(color>=0 && color<3 && offtime>=0 && offtime<256)
	{
		this->lights[color].offtime = offtime;
		this->lights[color].onofftime->setText( QString("%1/%2")
			.arg(this->lights[color].ontime)
			.arg(this->lights[color].offtime) );
	}
}

void WLed::loudspeaker(int freq, int num)
{
	printf("loudspeaker freq %d num %d\n", freq, num);
	
	if(freq>=0 && freq<256 && num>=0 && num<256)
		this->lspker->setText( QString("freq %1 num %2").arg(freq).arg(num) );
}

void WLed::showurb(int requesttype, int request, int value, int index, int length, char *data)
{
	static int id=0;
	
	char *tmp;
	
	if(length && data==0)
		return;
	
	tmp = this->urbmsgs[0]; 
	this->urbmsgs[0] = this->urbmsgs[1]; 
	this->urbmsgs[1] = this->urbmsgs[2]; 
	this->urbmsgs[2] = this->urbmsgs[3];
	this->urbmsgs[3] = tmp;
	
	sprintf(this->urbmsgs[3], "%d: typ %02x req %d val %04x ind %04x ", 
		++id, requesttype, request, value, index);
	
	static char buffer[100];
	if(length)
	  {
		sprintf(buffer, "len %d data %02x%02x%02x%02x%02x%02x%02x%02x", 
			length, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
		strcat(this->urbmsgs[3], buffer);
	  }
	 
	int j;
	for(j=0;j<4;j++)
		this->urb[j]->setText(this->urbmsgs[j]);
}
